﻿////////////////////////////////////////////////////////////////////////////
//DragDrop.js                                                             //
//Written by: Sam Burich                                                  //
//Adapted from: http://msdn.microsoft.com/en-us/magazine/cc135985.aspx    //
//Last Edited: 21 Mar 2012                                                //
//                                                                        //
//JavaScript is not object-oriented, and it has no "types". Mind = blown. //
//It makes programming really hard and awkward. Also, Javascript has all  //
//  this stuff going on in the background which is confusing initially.   //
//Plus, JavaScript notation is totally inconsistent. One method is called //
//  getDragData, using camel hump, while another is get_dragDataType,     //
//  which uses both camel hump and underscores! What is up with that?     //
//And there's basically no JavaScript documentation anywhere.             //
//One more thing! JavaScript will sometimes not wait for the currently    //
//  executing function to finish before moving on to the next one. This   //
//  becomes a huge problem when working on a machine with a slow internet //
//  connection. If the C# code isn't done before JavaScript decides it    //
//  wants to refresh the page, then the C# is out of luck! Frustrating.   //
//                                                                        //
//Anyway...                                                               //
//This code fakes two "classes": CourseBox (source)                       //
//  and SemesterRegion (target). These classes are used for the Graphical //
//  View of the application (drag and drop functionality). They implement //
//  two "interfaces".                                                     //
//                                                                        //
//I think that's what's happening, at least! Lots of magic going on here. //
////////////////////////////////////////////////////////////////////////////
Type.registerNamespace('AdviseUP.UI');

////////////////////
//Helper Functions//
////////////////////

//moveLabel()
//Used to make the semester regions look pretty.
//In actuality, this method just makes JavaScript wait around a second
//to ensure that the C# code and database procedures finish.
//dots - the number of dots to be displayed
//sem - the semester region
function moveLabel(dots, sem) {
    dots = dots + 1;
    if (dots == 0) {
        document.getElementById('SemMove' + sem).innerHTML = 'Moving';
        setTimeout(function () { moveLabel(0, sem); }, 250);
    }
    else if (dots == 1) {
        document.getElementById('SemMove' + sem).innerHTML = 'Moving.';
        setTimeout(function () { moveLabel(1, sem); }, 250);
    }
    else if (dots == 2) {
        document.getElementById('SemMove' + sem).innerHTML = 'Moving..';
        setTimeout(function () { moveLabel(2, sem); }, 250);
    }
    else if (dots == 3) {
        document.getElementById('SemMove' + sem).innerHTML = 'Moving...';
        setTimeout(function () { moveLabel(3, sem); }, 250);
    }
    else {
        setTimeout(function () { document.forms[0].submit(); }, 250);
    }
};

/////////////////////
//CourseBox "Class"//
/////////////////////

//CONSTRUCTOR
AdviseUP.UI.CourseBox = function (element, crn) {
    AdviseUP.UI.CourseBox.initializeBase(this, [element]);
    //Instance Variables
    this._mouseDownHandler = Function.createDelegate(this, this.mouseDownHandler);
    this._crn = crn;
    this._visual = null;
}

//METHODS
AdviseUP.UI.CourseBox.prototype =
{
    //"INTERFACE" METHODS
    get_dragDataType: function () {
        return 'DragDropColor';
    },

    getDragData: function (context) {
        return this._crn;
    },

    get_dragMode: function () {
        return Sys.Preview.UI.DragMode.Copy;
    },

    onDragStart: function () { },

    onDrag: function () { },

    onDragEnd: function (canceled) {
        if (this._visual) 
            this.get_element().parentNode.removeChild(this._visual);
        
    },

    //OTHER METHODS
    initialize: function () {
        AdviseUP.UI.CourseBox.callBaseMethod(this, 'initialize');
        $addHandler(this.get_element(), 'mousedown', this._mouseDownHandler);
    },

    mouseDownHandler: function (ev) {
        window._event = ev; //Required by JavaScript

        //Create the element that follows the pointer
        this._visual = this.get_element().cloneNode(true);
        this._visual.style.border = '1px solid Black';
        this._visual.style.opacity = '1';
        this._visual.style.width = '100px';
        this._visual.style.height = '40px';
        this._visual.style.marginLeft = '0px';
        this._visual.style.filter = 'progid:DXImageTransform.Microsoft.BasicImage(opacity=1)';
        this._visual.style.fontSize = '0px';
        this._visual.style.zIndex = 99999;
        this.get_element().parentNode.appendChild(this._visual);
        var location = Sys.UI.DomElement.getLocation(this.get_element());
        Sys.UI.DomElement.setLocation(this._visual, location.x, location.y);

        Sys.Preview.UI.DragDropManager.startDragDrop(this, this._visual, null);
    },

    dispose: function () {
        if (this._mouseDownHandler)
            $removeHandler(this.get_element(), 'mousedown', this._mouseDownHandler);
        this._mouseDownHandler = null;
        AdviseUP.UI.CourseBox.callBaseMethod(this, 'dispose');
    }
}

//REGISTRATION
AdviseUP.UI.CourseBox.registerClass('AdviseUP.UI.CourseBox', Sys.UI.Behavior, Sys.Preview.UI.IDragSource);

//////////////////////////
//SemesterRegion "Class"//
//////////////////////////

//CONSTRUCTOR
AdviseUP.UI.SemesterRegion = function (element, sem) {
    AdviseUP.UI.SemesterRegion.initializeBase(this, [element]);
    //Instance Variables
    this._sem = sem;
}

//METHODS
AdviseUP.UI.SemesterRegion.prototype =
{
    //"INTERFACE" METHODS
    get_dropTargetElement: function () {
        return this.get_element();
    },

    canDrop: function (dragMode, dataType, data) {
        return (dataType == 'DragDropColor' && data);
    },

    drop: function (dragMode, dataType, data) {
        if (dataType == 'DragDropColor' && data) {
            //This is the code that sends the data back to C#
            this.get_element().style.backgroundColor = '#B3D9FF'; //Moving... background-color
            this.get_element().style.color = '#000000';
            PageMethods.MoveCourse(data, this._sem);
            moveLabel(-1, this._sem);
        }
    },

    onDragEnterTarget: function (dragMode, dataType, data) {
        // Highlight the drop zone by changing its background color
        if (dataType == 'DragDropColor' && data) {
            this.get_element().style.backgroundColor = '#0000FF'; //Highlight column to be moved to before 'Moving...' background-color
            this.get_element().style.color = '#0000FF';
        }
    },

    onDragLeaveTarget: function (dragMode, dataType, data) {
        // Unhighlight the drop zone
        if (dataType == 'DragDropColor' && data) {
            this.get_element().style.backgroundColor = '#DDDDDD'; //Highlight column to be moved from before 'Moving...' background-color
            this.get_element().style.color = '#DDDDDD';
        }
    },

    onDragInTarget: function (dragMode, dataType, data) { },

    //OTHER METHODS
    initialize: function () {
        AdviseUP.UI.SemesterRegion.callBaseMethod(this, 'initialize');
        Sys.Preview.UI.DragDropManager.registerDropTarget(this);
    },

    dispose: function () {
        Sys.Preview.UI.DragDropManager.unregisterDropTarget(this);
        AdviseUP.UI.SemesterRegion.callBaseMethod(this, 'dispose');
    }
}

//REGISTRATION
AdviseUP.UI.SemesterRegion.registerClass('AdviseUP.UI.SemesterRegion', Sys.UI.Behavior, Sys.Preview.UI.IDropTarget);

/////////////////
//Other Actions//
/////////////////

//REGISTER SCRIPT
Sys.Application.notifyScriptLoaded();
